package com.shelpe.services.sinbad.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.shelpe.services.sinbad.dao.KeywordMapper;
import com.shelpe.services.sinbad.entity.jpa.Adgroup;
import com.shelpe.services.sinbad.entity.jpa.Campaign;
import com.shelpe.services.sinbad.model.CampaignidAndKeywordids;
import com.shelpe.services.sinbad.model.Keyword;
import com.shelpe.services.sinbad.model.KeywordExample;
import com.shelpe.services.sinbad.model.KeywordsLog;
import com.shelpe.services.sinbad.model.KeywordsLog.Action;
import com.shelpe.services.sinbad.model.RptKeyword;
import com.shelpe.services.sinbad.model.RptKeywordParam;
import com.shelpe.services.sinbad.repository.jpa.AdgroupRepository;
import com.shelpe.services.sinbad.repository.jpa.CampaignRepository;
import com.shelpe.services.sinbad.service.KeywordService;
import com.shelpe.services.sinbad.service.KeywordsLogService;
import com.shelpe.services.sinbad.service.RptKeywordService;
import com.shelpe.services.sinbad.service.UserService;
import com.shelpe.services.sinbad.service.simbaproxy.SimbaProxy;

import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Controller
@Getter
@Setter
@RequestMapping("/sinbadservice")
public class KeywordController {

	@Autowired
	SimbaProxy simbaProxy;

	@Autowired
	KeywordService keywordService;
	
	@Autowired
	private KeywordMapper keywordMapper;

	@Autowired
	RptKeywordService rptKeywordService;

	@Autowired
	KeywordsLogService keywordsLogService;

	@Autowired
	UserService userService;

	@Autowired
	private AdgroupRepository adgroupRepository;
	@Autowired
	private CampaignRepository campaignRepository;

	private ExecutorService threadPool = Executors.newFixedThreadPool(4);

	/**
	 * 执行思路时候,记录日志,供gateway调用
	 * 
	 * @return
	 */
	@RequestMapping(method = RequestMethod.POST, value = "/keyword/logs")
	public @ResponseBody boolean keywordLog(@RequestBody List<KeywordsLog> logs) {
		log.info("logs:{}", JSON.toJSONString(logs));
		KeywordsLog oldLog = null;
		for (KeywordsLog record : logs) {

			oldLog = keywordsLogService.getOne(record.getKeywordId());

			JSONObject retObj = new JSONObject();

			if (oldLog != null) {
				if (oldLog.getNote() != null) {
					JSONObject note = JSON.parseObject(oldLog.getNote());
					if (note != null && note.containsKey("new")) {
						retObj.put("old", note.getString("new"));
					} else {
						retObj.put("old", oldLog.getNote());
					}
				}
			}

			retObj.put("new", record.getNote());
			record.setNote(retObj.toJSONString());

			keywordsLogService.save(record);
		}
		return true;
	}

	/**
	 * 卡位详情调用
	 * 
	 * @param keywordId
	 * @return
	 */
	@RequestMapping("/users/{userId}/keywords/{keywordId}/data")
	public @ResponseBody RptKeyword keywrodData(@PathVariable("userId") Long userId,
			@PathVariable("keywordId") Long keywordId, @RequestParam(defaultValue = "7") Integer days,
			@RequestParam(required = false) Integer device) {
		log.info("s RequestParam userId:{} keywordId:{} days:{} device:{}", userId, keywordId, days, device);
		RptKeywordParam param = new RptKeywordParam();
		param.setUserId(userId);
		param.setKeywordId(keywordId);
		param.setDay(days);
		if (device != null) {
			param.setSource(device.byteValue());
		}
		return rptKeywordService.selectSum(param);
	}

	/**
	 * 关键词 趋势图
	 * 
	 * @param adgroupId
	 * @param keywordId
	 * @param days
	 * @param device
	 * @return
	 */
	@RequestMapping("/adgroups/{adgroup_id}/keywords/{keyword_id}/reports/trend")
	public @ResponseBody Object reportsTrend(@PathVariable("adgroup_id") Long adgroupId,
			@PathVariable("keyword_id") Long keywordId, @RequestParam(defaultValue = "7") Integer days,
			@RequestParam(required = false) Integer device) {
		log.info("reportsTrend RequestParam adgroupId:{} days:{} device:{}", adgroupId, days, device);
		RptKeywordParam param = new RptKeywordParam();
		param.setUserId(adgroupRepository.findOne(adgroupId).getUserID());
		param.setAdgroupId(adgroupId);
		param.setKeywordId(keywordId);
		param.setDay(days);
		if (device != null) {
			param.setSource(device.byteValue());
		}
		return rptKeywordService.getReportsTrendByDate(param);
	}

	/**
	 * 关键词 指标摘要
	 * 
	 * @param adgroupId
	 * @param days
	 * @param device
	 * @return
	 */
	@RequestMapping("/adgroups/{adgroup_id}/keywords/{keyword_id}/summaries/metric")
	public @ResponseBody Object summariesMetric(@PathVariable("adgroup_id") Long adgroupId,
			@PathVariable("keyword_id") Long keywordId, @RequestParam(defaultValue = "7") Integer days,
			@RequestParam(required = false) Integer device) {
		log.info("summariesMetric RequestParam adgroupId:{} days:{} device:{}", adgroupId, days, device);
		RptKeywordParam param = new RptKeywordParam();
		param.setUserId(adgroupRepository.findOne(adgroupId).getUserID());
		param.setAdgroupId(adgroupId);
		param.setKeywordId(keywordId);
		param.setDay(days);
		if (device != null) {
			param.setSource(device.byteValue());
		}
		return rptKeywordService.getSummariesMetric(param);
	}

	/**
	 * 关键词出价
	 * 
	 * @param userId
	 * @param adgroupId
	 * @param driveType 默认0(自动)
	 * @param prices
	 * @return
	 * @throws ExecutionException
	 * @throws InterruptedException
	 */
	@RequestMapping(method = RequestMethod.POST, value = "/users/{userId}/adgroups/{adgroupId}/keywords/price")
	public @ResponseBody Object setPrice(@PathVariable("userId") Long userId, @PathVariable("adgroupId") Long adgroupId,
			@RequestParam(defaultValue = "0") Integer driveType,
			@RequestBody String priceString) throws InterruptedException, ExecutionException {
		log.info("/users/{userId}/adgroups/{adgroupId}/keywords/price params userId:{} adgroupId:{} prices:{}", userId,
				adgroupId, priceString);
		String nick = userService.getNick(userId);
		JSONArray setpriceArray = JSON.parseArray(priceString);
		List<FutureTask<String>> strFutures = new ArrayList<FutureTask<String>>();
		FutureTask<String> future = null;

		List<String> priceList = new ArrayList<String>();
		List<String> outPriceList = new ArrayList<String>();
		String prices = null;
		int limit = 25;
		for (int i = 0; i <= setpriceArray.size() / limit; i++) {
			if (i == setpriceArray.size() / limit) {
				// 最后一页
				if (i * limit < setpriceArray.size()) {// not null
					prices = setpriceArray.subList(i * limit, setpriceArray.size()).toString();
					priceList.add(prices);
					future = (FutureTask<String>) threadPool.submit(new SetPriceTask(nick, prices));
					strFutures.add(future);
				}
			} else {
				prices = setpriceArray.subList(i * limit, (i + 1) * limit).toString();
				priceList.add(prices);
				future = (FutureTask<String>) threadPool.submit(new SetPriceTask(nick, prices));
				strFutures.add(future);
			}
		}

		for (FutureTask<String> ft : strFutures) {
			String ret = ft.get();
			log.info(">>>>>>>>>>>>>>>>>>taobaoAPI setPrice:{}", ret);
			if (ret.contains("simba_keywords_pricevon_set_response")) {
				JSONObject obj = JSON.parseObject(ret);
				JSONArray arr = obj.getJSONObject("simba_keywords_pricevon_set_response").getJSONObject("keywords")
						.getJSONArray("keyword");
				JSONObject wordjson;
				com.shelpe.services.sinbad.model.Keyword keyword;
				KeywordsLog log = null;
				KeywordsLog oldLog = null;
				if (arr != null) {
					for (Iterator<Object> iter = arr.iterator(); iter.hasNext();) {
						wordjson = (JSONObject) iter.next();
						keyword = JSON.parseObject(wordjson.toJSONString(),
								com.shelpe.services.sinbad.model.Keyword.class);
						keywordService.update(keyword, userId);
						log = new KeywordsLog();
						log.setKeywordId(keyword.getKeywordId());
						log.setUpdatedTime(new Date());
						if(driveType==0){
							log.setAction((byte) Action.AUTO_CHANGE_PRICE.getValue());
						}else{
							log.setAction((byte) Action.MANUAL_CHANGE_PRICE.getValue());
						}
						log.setAdgroupId(keyword.getAdgroupId().intValue());
						log.setKeyword(keyword.getWord());
						log.setNewIntVal(keyword.getMaxMobilePrice());

						oldLog = keywordsLogService.getOne(keyword.getKeywordId());
						JSONObject retObj = new JSONObject();

						if (oldLog != null) {
							if (oldLog.getNote() != null) {
								JSONObject note = JSON.parseObject(oldLog.getNote());
								if (note != null && note.containsKey("new")) {
									retObj.put("old", note.getString("new"));
								} else {
									retObj.put("old", oldLog.getNote());
								}
							}
						}

						retObj.put("new", wordjson);
						log.setNote(retObj.toJSONString());

						keywordsLogService.save(log);
					}
				}
			} else {

			}
			outPriceList.add(ret);
		}
		return outPriceList.size() > 0;
	}

	/**
	 * 取得一个推广组的所有关键词
	 * 
	 * @param nick
	 * @param adgroupId
	 * @return
	 */
	@RequestMapping("/users/{userId}/adgroups/{adgroupId:[\\d]+}/keywords")
	public @ResponseBody Object getKeywords(@PathVariable("userId") Long userId,
			@PathVariable("adgroupId") Long adgroupId) {
		log.info("requestParams userId:{} -groupId:{}", userId, adgroupId);
		String nick = userService.getNick(userId);
		log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>nick:{}", nick);
		Object objs = simbaProxy.getKeywords(nick, adgroupId);
		return objs;
	}

	/**
	 * 创建一批关键词
	 * 
	 * @return
	 * @throws ExecutionException
	 * @throws InterruptedException
	 */
	@RequestMapping(method = RequestMethod.POST, value = "/users/{userId}/adgroups/{adgroupId}/keywords")
	public @ResponseBody Object addKeywords(@PathVariable("userId") Long userId,
			@PathVariable("adgroupId") Long adgroupId, @RequestParam(defaultValue = "0") Integer driveType, @RequestBody String keywordPrices)
			throws InterruptedException, ExecutionException {

		String nick = userService.getNick(userId);

		log.info("addKeywords nick:{}  userId:{}  adgroupId:{}  keywordPrices：{}", nick, userId, adgroupId,
				keywordPrices);
		JSONArray array = JSON.parseArray(keywordPrices);
		JSONArray tempArray = new JSONArray();

		ExecutorService threadPool = Executors.newFixedThreadPool(4);
		List<FutureTask<JSONArray>> futures = new ArrayList<FutureTask<JSONArray>>();
		// AddKeywordTask task = null;

		Map<String, JSONObject> map = new HashMap<String, JSONObject>();
		for (int i = 0; i < array.size(); i++) {
			JSONObject obj = array.getJSONObject(i);
			map.put(obj.getString("word"), obj);
			tempArray.add(obj);
			if (tempArray.size() % 30 == 0) {
				// TODO 执行
				FutureTask<JSONArray> future = (FutureTask<JSONArray>) threadPool
						.submit(new AddKeywordTask(userId, adgroupId, nick, tempArray.toJSONString(), driveType));
				futures.add(future);
				tempArray.clear();
			}
		}
		// TODO 执行tempArray
		if (tempArray.size() > 0) {
			FutureTask<JSONArray> future = (FutureTask<JSONArray>) threadPool
					.submit(new AddKeywordTask(userId, adgroupId, nick, tempArray.toJSONString(), driveType));
			futures.add(future);
		}
		threadPool.shutdown();

		JSONObject jsonObj = new JSONObject();
		JSONObject jsonWords = new JSONObject();
		JSONObject jsonWord = new JSONObject();
		JSONArray wordArray = new JSONArray();
		JSONArray addKeywordErrorArray = new JSONArray();

		JSONArray setpriceArray = new JSONArray();
		JSONObject priceObj = null;
		for (FutureTask<JSONArray> future : futures) {
			JSONArray a = (JSONArray) future.get();
			log.info("addKeywords:{}", a.toJSONString());
			if(!a.toJSONString().contains("error_response")){
				for (int i = 0; i < a.size(); i++) {
					JSONObject obj = a.getJSONObject(i);
					wordArray.add(obj);
					// 构建修改出价的字符串参数 Example
					// {"keywordId":"286759816920","maxPrice":"95","matchScope":"4","mobileIsDefaultPrice":0,"maxMobilePrice":"100"},
					priceObj = new JSONObject();
					if (obj.containsKey("keyword_id")) {
						if (map.get(obj.getString("word")) != null) {
							priceObj = map.get(obj.getString("word"));
							priceObj.remove("word");
							priceObj.put("keywordId", obj.getLong("keyword_id"));
							setpriceArray.add(priceObj);
						}
					}
				}
			}else{//error_response
				//{"error_response":{"msg":"Remote service error","code":15,"sub_msg":"请勿重复添加关键词",
				//                   "sub_code":"isp.internal-error","request_id":"rxmpywtwz7pr"}}
				for (int i = 0; i < a.size(); i++) {
					JSONObject obj = a.getJSONObject(i);
					addKeywordErrorArray.add(obj);
				}
			}
		}

		threadPool = Executors.newFixedThreadPool(4);
		List<FutureTask<String>> strFutures = new ArrayList<FutureTask<String>>();
		FutureTask<String> future = null;

		List<String> priceList = new ArrayList<String>();
		List<String> outPriceList = new ArrayList<String>();
		String prices = null;
		int limit = 25;
		for (int i = 0; i <= setpriceArray.size() / limit; i++) {
			if (i == setpriceArray.size() / limit) {
				// 最后一页
				if (i * limit < setpriceArray.size()) {// not null
					prices = setpriceArray.subList(i * limit, setpriceArray.size()).toString();
					priceList.add(prices);
					future = (FutureTask<String>) threadPool.submit(new SetPriceTask(nick, prices));
					strFutures.add(future);
				}
			} else {
				prices = setpriceArray.subList(i * limit, (i + 1) * limit).toString();
				priceList.add(prices);
				future = (FutureTask<String>) threadPool.submit(new SetPriceTask(nick, prices));
				strFutures.add(future);
			}
		}

		threadPool.shutdown();
		for (FutureTask<String> ft : strFutures) {
			String ret = ft.get();
			log.info("simba_keywords_pricevon_set_response:{}", ret);
			if (ret.contains("simba_keywords_pricevon_set_response")) {
				JSONObject obj = JSON.parseObject(ret);
				JSONArray arr = obj.getJSONObject("simba_keywords_pricevon_set_response").getJSONObject("keywords")
						.getJSONArray("keyword");
				JSONObject wordjson;
				com.shelpe.services.sinbad.model.Keyword keyword;
				KeywordsLog log = null;
				KeywordsLog oldLog = null;
				if (arr != null) {
					for (Iterator<Object> iter = arr.iterator(); iter.hasNext();) {
						wordjson = (JSONObject) iter.next();
						keyword = JSON.parseObject(wordjson.toJSONString(),
								com.shelpe.services.sinbad.model.Keyword.class);
						keywordService.update(keyword, userId);
						log = new KeywordsLog();
						log.setKeywordId(keyword.getKeywordId());
						log.setUpdatedTime(new Date());
						log.setAction((byte) Action.AUTO_CHANGE_PRICE.getValue());
						log.setAdgroupId(keyword.getAdgroupId().intValue());
						log.setKeyword(keyword.getWord());
						log.setNewIntVal(keyword.getMaxMobilePrice());
						oldLog = keywordsLogService.getOne(keyword.getKeywordId());
						JSONObject retObj = new JSONObject();
						JSONObject note = JSON.parseObject(oldLog.getNote());
						if (note != null && note.containsKey("new")) {
							retObj.put("old", note.getString("new"));
						} else {
							retObj.put("old", oldLog.getNote());
						}
						retObj.put("new", wordjson);
						log.setNote(retObj.toJSONString());

						keywordsLogService.save(log);
					}
				}
			}else{//error_response
				
			}
			outPriceList.add(ret);
		}

		jsonWord.put("keyword", wordArray);
		jsonWords.put("keywords", jsonWord);//成功信息
		jsonWords.put("errors", addKeywordErrorArray);//失败信息
		jsonObj.put("simba_keywordsvon_add_response", jsonWords);

		jsonObj.put("inprices", priceList);
		jsonObj.put("outprices", outPriceList);

		return jsonObj;
	}

	private List<Long> getAdgroupIds(String adgroupId, String campaignId){
		List<Long> adgroupIds = new ArrayList<Long>();
		log.info("getAdgroupIds params adgroupId:{} campaignId:{}", adgroupId, campaignId);
		if(adgroupId!=null){
			for(String adgroupid : adgroupId.split(",")){
				adgroupIds.add(Long.valueOf(adgroupid));
			}
		}
		if(campaignId!=null){
			for(String campaignid : campaignId.split(",")){
				List<Adgroup> groups = adgroupRepository.findByCampaignID(Long.valueOf(campaignid));
				for(Adgroup group : groups){
					adgroupIds.add(group.getAutoID());
				}
			}
		}
		if(log.isInfoEnabled()){
			log.info("adgroupIds:{}", adgroupIds.toString());
		}
		return adgroupIds;
	}
	
	/**
	 * 删除垃圾词 - 查询符合条件的垃圾词
	 * @param userId          用户ID
	 * @param campaignIds     推广计划ids
	 * @param adgroupIds      推广组ids
	 * @param clickDay        查询点击量的天数
	 * @param impressionsDay  查询展现量的天数
	 * @param qscore          PC质量得分
	 * @param mobileQscore    无线质量得分
	 * @return
	 */
	@RequestMapping(method = RequestMethod.GET, value = "/spamwords")
	public @ResponseBody SpamKeywordsDto spamwords(@RequestParam(required = false) Long userId,
			@RequestParam(required = false) List<Long> campaignIds, @RequestParam(required = false) List<Long> adgroupIds,
			@RequestParam(required = false) Integer clickDay, @RequestParam(required = false) Integer impressionsDay,
		    @RequestParam(required = false) Integer qscore,
			@RequestParam(required = false) Integer mobileQscore) {
		long start = System.currentTimeMillis();

		if (userId == null) {
			if(adgroupIds != null && adgroupIds.size() > 0){
				Adgroup adgroup = adgroupRepository.findOne(adgroupIds.get(0));
				userId = adgroup.getUserID();
			}else if(campaignIds != null && campaignIds.size() > 0){
				Campaign campaign = this.campaignRepository.findOne(campaignIds.get(0));
				userId = campaign.getUserID();
			}
			
			if(userId == null){
				throw new IllegalArgumentException("userID_not_found");
			}
		}

		RptKeywordParam param = new RptKeywordParam();
		param.setUserId(userId);
		if(adgroupIds != null && adgroupIds.size() > 0){
			param.setAdgroupIds(adgroupIds);
		}
		if(campaignIds != null && campaignIds.size() > 0){
			param.setCampaignIds(campaignIds);
		}
		if(clickDay != null){
			param.setClickDay(clickDay);
		}
		if(impressionsDay != null){
			param.setImpressionsDay(impressionsDay);
		}
		if (qscore != null) {
			param.setQscore(qscore);
		}
		if (mobileQscore != null) {
			param.setMobileQscore(mobileQscore);
		}

		List<RptKeywordService.KeywordCompositeID> ids = rptKeywordService.getKeywordIds(param);
		SpamKeywordsDto dto = new SpamKeywordsDto();
		dto.setUserID(userId);
		if (ids != null && ids.size() > 0) {
			//查看在keyword表中是否存在
			List<Long> foundKeywordIDs = new ArrayList<Long>();
			for(RptKeywordService.KeywordCompositeID id: ids){
				foundKeywordIDs.add(id.getKeywordID());
			}
			KeywordExample ke =new KeywordExample();
			ke.setUserId(userId);
			ke.createCriteria().andKeywordIdIn(foundKeywordIDs);
			List<Keyword> foundKeywords = this.keywordMapper.selectByExample(ke);
			foundKeywordIDs = new ArrayList<Long>();
			for(Keyword kw:foundKeywords){
				foundKeywordIDs.add(kw.getKeywordId());
			}
			
			dto.setCount(foundKeywords.size());
			Map<Long, CampaignSpamKeywords> map = new HashMap<Long, CampaignSpamKeywords>();
			for(RptKeywordService.KeywordCompositeID id:ids){
				if(foundKeywordIDs.contains(id.getKeywordID())){
					CampaignSpamKeywords csk = map.get(id.getCampaignID());
					if(csk == null){
						csk = new CampaignSpamKeywords();
						csk.setCampaignID(id.getCampaignID());
						map.put(id.getCampaignID(), csk);
					}
					csk.addKeywordID(id.getKeywordID());
				}
			}
			dto.setKeywords(new ArrayList<CampaignSpamKeywords>());
			for(CampaignSpamKeywords csk:map.values()){
				dto.getKeywords().add(csk);
			}
		}
		
		log.info("select spamwords cost {} ms", System.currentTimeMillis() - start, param);
		return dto;
	}
	
	@Data
	@JsonInclude(Include.NON_NULL)
	public static class SpamKeywordsDto{
		private int count;
		@JsonProperty("user_id")
		private long userID;
		private List<CampaignSpamKeywords> keywords;
	}
	
	@Data
	private static class CampaignSpamKeywords{
		@JsonProperty("campaign_id")
		private long campaignID;
		@JsonProperty("keyword_ids")
		private List<Long> keywordIDs;
		
		public void addKeywordID(long keywordID){
			if(this.keywordIDs == null){
				this.keywordIDs = new ArrayList<Long>();
			}
			this.keywordIDs.add(keywordID);
		}
	}

	/**
	 * 删除垃圾词 - 确认删除
	 * @param userId
	 * @param keywordIds
	 * @return
	 */
	@RequestMapping(method = RequestMethod.POST, value = "/users/{userId}/spamwords")
	public @ResponseBody boolean del(@PathVariable("userId") Long userId, @RequestBody JSONObject ids) {
		log.info("spamwords delete userId:{}  keywordIds：{}", userId, ids);
		String keywordIds = "";
		if(ids.containsKey("keywordIds")){
			keywordIds = ids.getString("keywordIds");
		}
		
		boolean ret = true;
		List<CampaignidAndKeywordids> ckids = keywordService.getCampaignidAndKeywordids(userId, keywordIds);
		Object obj;
		for(CampaignidAndKeywordids ckid : ckids){
			log.info("spamwords delete campaignid:{} \n   keywordids:{}", ckid.getCampaignId(), ckid.getKeywordIds());
			obj = delKeywords(userId, ckid.getCampaignId(), ckid.getKeywordIds());
			if(obj.toString().contains("error_response")){
				log.info("spamwords delete error result: {}", obj.toString());
				ret = false;
			}
		}
		return ret;
	};
	
	@RequestMapping(method = RequestMethod.DELETE, value = "/users/{userId}/campaigns/{campaignId}/keywords")
	public @ResponseBody Object delKeywordsByDel(@PathVariable("userId") Long userId,
			@PathVariable("campaignId") Long campaignId, @RequestParam String keywordIds) {
		log.info("delete keyword userId:{}  campaignId:{}  keywordIds：{}", userId, campaignId, keywordIds);
		return delKeywords(userId, campaignId, keywordIds);
	}

	@RequestMapping(method = RequestMethod.POST, value = "/users/{userId}/campaigns/{campaignId}/keywords")
	public @ResponseBody Object delKeywordsByPost(@PathVariable("userId") Long userId,
			@PathVariable("campaignId") Long campaignId, @RequestBody String keywordIds) {
		log.info("post deleteKeyword userId:{}  campaignId:{}  keywordIds：{}", userId, campaignId, keywordIds);
		return delKeywords(userId, campaignId, keywordIds);
	};

	private Object delKeywords(Long userId, Long campaignId, String keywordIds) {
		String nick = userService.getNick(userId);
		Object obj = null;
		String[] ids = keywordIds.split(",");
		if (ids.length > 100) {
			return "keywordids too many!";
		} else {
			Long[] longids = new Long[ids.length];
			int i = 0;
			for (String id : ids) {
				longids[i] = Long.valueOf(id.trim());
				i++;
			}

			if (campaignId == null) {
				log.info("delKeywords campaignId is null, finding...");
				List<RptKeyword> rpts = rptKeywordService.select(longids[0], null, null, userId);
				if (!rpts.isEmpty()) {
					campaignId = rpts.get(0).getCampaignId();
				}
			}

			log.debug("del keyword ids:{}", longids.toString());
			obj = simbaProxy.delKeywords(nick, campaignId, longids);
			log.info("del keyword result: {}", obj);
			if(!obj.toString().contains("error_response")){
				keywordService.delete(userId, keywordIds);
				rptKeywordService.delete(userId, keywordIds);
				KeywordsLog record = null;
				for (Long keywordId : longids) {
					record = keywordsLogService.getOne(keywordId);
					if(record.getId()!=null){
						record.setId(null);
						record.setUpdatedTime(new Date());
						record.setAction((byte) Action.MANUAL_DEL_KEYWORD.getValue());
						keywordsLogService.save(record);
					}
				}
			}
		}
		return obj;
	}

	@RequestMapping("/log/{keywordId}")
	public @ResponseBody Object get(@PathVariable("keywordId") Long keywordId) {
		return keywordsLogService.getOne(keywordId);
	}

	/**
	 * 根据用户ID 读取该用户所有keyword
	 * 
	 * @param userId
	 * @return
	 */
	@RequestMapping("/users/{userId}/keywords")
	public @ResponseBody List<com.shelpe.services.sinbad.model.Keyword> keywordsbyuser(
			@PathVariable("userId") Long userId) {
		return keywordService.getKeywords(userId);
	}

	/**
	 * 根据推广组ID 读取该用户所有keyword
	 * 
	 * @param adgroupId
	 * @return
	 */
	/*@RequestMapping("/adgroups/{adgroupId}/keywords")
	public @ResponseBody List<com.shelpe.services.sinbad.model.Keyword> keywords(
			@PathVariable("adgroupId") String adgroupId) {
		Long userId = adgroupRepository.findOne(Long.valueOf(adgroupId)).getUserID();
		return keywordService.getKeywords(userId, adgroupId, null);
	}*/

	// 修改出价任务
	class SetPriceTask implements Callable<String> {
		String nick;
		String priceString;

		public SetPriceTask(String nick, String priceString) {
			log.info("SetPriceTask nick：{} priceString:{}", nick, priceString);
			this.nick = nick;
			this.priceString = priceString;
		}

		@Override
		public String call() throws Exception {
			return simbaProxy.setPricevon(nick, priceString);
		}
	}

	// 添加的关键词任务
	private class AddKeywordTask implements Callable<JSONArray> {
		Long userId;
		String nick;
		Long adgroupId;
		String keywordPrices;
		Integer driveType;

		public AddKeywordTask(Long userId, Long adgroupId, String nick, String keywordPrices, Integer driveType) {
			this.userId = userId;
			this.adgroupId = adgroupId;
			this.nick = nick;
			this.keywordPrices = keywordPrices;
			this.driveType = driveType;
		}

		@Override
		public JSONArray call() throws Exception {
			Object obj = simbaProxy.addKetwords(nick, adgroupId, keywordPrices);
			log.info("keywordPrices in addKeywords :{}", keywordPrices);
			log.info("simba_keywordsvon_add_response in addKeywords :{}", obj.toString());
			JSONArray jsonArray = null;
			if (obj.toString().contains("simba_keywordsvon_add_response")) {
				JSONObject jsonObj = JSON.parseObject(JSON.toJSONString(obj));
				jsonArray = jsonObj.getJSONObject("simba_keywordsvon_add_response").getJSONObject("keywords")
						.getJSONArray("keyword");
				JSONObject wordjson;
				com.shelpe.services.sinbad.model.Keyword keyword;
				KeywordsLog log = null;
				KeywordsLog oldLog = null;
				if (jsonArray != null) {
					Adgroup adgroup = adgroupRepository.findOne(adgroupId);
					for (Iterator<Object> iter = jsonArray.iterator(); iter.hasNext();) {
						wordjson = (JSONObject) iter.next();
						keyword = JSON.parseObject(wordjson.toJSONString(),
								com.shelpe.services.sinbad.model.Keyword.class);
						if (keyword.getMaxMobilePrice() == null) {
							keyword.setMaxMobilePrice((keyword.getMaxPrice() * adgroup.getMobileDiscount()) / 100);
						}
						keywordService.save(keyword, userId);
						log = new KeywordsLog();
						log.setKeywordId(keyword.getKeywordId());
						log.setUpdatedTime(new Date());
						if(driveType==0){
							log.setAction((byte) Action.AUTO_NEW_KEYWORD.getValue());
						}else{
							log.setAction((byte) Action.MANUAL_NEW_KEYWORD.getValue());
						}
						log.setAdgroupId(keyword.getAdgroupId().intValue());
						log.setKeyword(keyword.getWord());
						log.setNewIntVal(keyword.getMaxMobilePrice());

						oldLog = keywordsLogService.getOne(keyword.getKeywordId());
						JSONObject retObj = new JSONObject();
						if (oldLog != null) {
							JSONObject note = JSON.parseObject(oldLog.getNote());
							if (note != null && note.containsKey("new")) {
								retObj.put("old", note.getString("new"));
							} else {
								retObj.put("old", oldLog.getNote());
							}
						}
						retObj.put("new", wordjson);
						log.setNote(retObj.toJSONString());
						keywordsLogService.save(log);
					}
				}
			} else {
				jsonArray = new JSONArray();
				jsonArray.add(JSON.parseObject(JSON.toJSONString(obj)));
			}
			return jsonArray;
		}
	}

}
